package com.study.talk.netty.message.code;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.study.talk.netty.message.MessageType;
import com.study.talk.netty.message.TalkMessage;
import com.study.talk.netty.message.request.AcceptGroupRequest;
import com.study.talk.netty.message.request.AcceptJoinGroupRequest;
import com.study.talk.netty.message.request.AcceptRequest;
import com.study.talk.netty.message.request.AddUserRequest;
import com.study.talk.netty.message.request.ApplyGroupRequest;
import com.study.talk.netty.message.request.CreateGroupRequest;
import com.study.talk.netty.message.request.GroupMessageRequest;
import com.study.talk.netty.message.request.HeartBeatRequest;
import com.study.talk.netty.message.request.InviteGroupRequest;
import com.study.talk.netty.message.request.LoginRequest;
import com.study.talk.netty.message.request.MessageRequest;
import com.study.talk.netty.message.request.RegisterRequest;
import com.study.talk.netty.message.request.SmsSendRequest;
import com.study.talk.netty.message.request.SyncMessageRequest;
import com.study.talk.netty.message.response.AcceptGroupResponse;
import com.study.talk.netty.message.response.AcceptJoinGroupResponse;
import com.study.talk.netty.message.response.AcceptResponse;
import com.study.talk.netty.message.response.AddUserResponse;
import com.study.talk.netty.message.response.AddUserSelfResponse;
import com.study.talk.netty.message.response.ApplyGroupResponse;
import com.study.talk.netty.message.response.ApplyGroupSelfResponse;
import com.study.talk.netty.message.response.CreateGroupResponse;
import com.study.talk.netty.message.response.GroupMessageResponse;
import com.study.talk.netty.message.response.HeartBeatResponse;
import com.study.talk.netty.message.response.InviteGroupResponse;
import com.study.talk.netty.message.response.InviteGroupSelfResponse;
import com.study.talk.netty.message.response.LoginResponse;
import com.study.talk.netty.message.response.MessageResponse;
import com.study.talk.netty.message.response.MessageSelfResponse;
import com.study.talk.netty.message.response.RegisterResponse;
import com.study.talk.netty.message.response.SmsSendResponse;
import com.study.talk.netty.serializer.Serializer;

import io.netty.buffer.ByteBuf;

public class MessageCode {
    
    public static final MessageCode INSTANCE = new MessageCode();
    
    private MessageCode() {
    }
    public static final int MAGIC_NUMBER = 0x12345678;
    
    public void encode(ByteBuf byteBuf, TalkMessage message) {
        byte[] bytes = Serializer.Default.serializer(message);
        //魔数
        byteBuf.writeInt(MAGIC_NUMBER);
        //版本
        byteBuf.writeByte(message.getVersion());
        //序列化方式
        byteBuf.writeByte(Serializer.Default.getSerializerAlgorithm());
        //消息类型
        byteBuf.writeByte(message.getType());
        //消息长度
        byteBuf.writeInt(bytes.length);
        byteBuf.writeBytes(bytes);
    }
    
    public TalkMessage decode(ByteBuf byteBuf) {
        //跳过魔术
        byteBuf.skipBytes(4);
        //跳过版本
        byteBuf.skipBytes(1);
        // 序列化算法
        byte serializeAlgorithm = byteBuf.readByte();
        // 消息类型
        byte MessageType = byteBuf.readByte();
        //长度
        int length = byteBuf.readInt();
        byte [] bytes = new byte[length];
        byteBuf.readBytes(bytes);
        Class<? extends TalkMessage> messageClass = getMessageByMessageType(MessageType);
        Serializer serializer = getSerializer(serializeAlgorithm);
        return serializer.deSerializer(messageClass, bytes);

    }


    public TalkMessage decode(String json) {
        JSONObject jsonObject = JSON.parseObject(json);
        int command = (int) jsonObject.get("command");
        Class<? extends TalkMessage> clazz = getMessageByMessageType((byte) command);
        return jsonObject.toJavaObject(clazz);
    }
    public static Class<? extends TalkMessage> getMessageByMessageType(byte type) {
        return switch (type) {
            case MessageType.LOGIN_REQUEST -> LoginRequest.class;
            case MessageType.LOGIN_RESPONSE -> LoginResponse.class;
            case MessageType.SEND_MESSAGE_RESPONSE -> MessageResponse.class;
            case MessageType.ADD_USER_REQUEST -> AddUserRequest.class;
            case MessageType.ADD_USER_RESPONSE -> AddUserResponse.class;
            case MessageType.ADD_USER_SELF_RESPONSE -> AddUserSelfResponse.class;
            case MessageType.CREATE_GROUP_REQUEST -> CreateGroupRequest.class;
            case MessageType.CREATE_GROUP_RESPONSE -> CreateGroupResponse.class;
            case MessageType.INVITE_GROUP_REQUEST -> InviteGroupRequest.class;
            case MessageType.INVITE_GROUP_RESPONSE -> InviteGroupResponse.class;
            case MessageType.INVITE_GROUP_SELF_RESPONSE -> InviteGroupSelfResponse.class;
            case MessageType.GROUP_MESSAGE_REQUEST -> GroupMessageRequest.class;
            case MessageType.GROUP_MESSAGE_RESPONSE -> GroupMessageResponse.class;
            case MessageType.ACCEPT_GROUP_REQUEST -> AcceptGroupRequest.class;
            case MessageType.ACCEPT_GROUP_RESPONSE -> AcceptGroupResponse.class;
            case MessageType.ACCEPT_REQUEST -> AcceptRequest.class;
            case MessageType.ACCEPT_RESPONSE -> AcceptResponse.class;
            case MessageType.REGISTER_REQUEST -> RegisterRequest.class;
            case MessageType.REGISTER_RESPONSE -> RegisterResponse.class;
//            case MessageType.UPDATE_PASSWD_REQUEST :
//                return UpdatePasswdRequest.class;
//            case MessageType.UPDATE_PASSWD_RESPONSE :
//                return UpdatePasswdResponse.class;
            case MessageType.MESSAGE_SELF_RESPONSE -> MessageSelfResponse.class;
            case MessageType.HEAT_BEAT_REQUEST -> HeartBeatRequest.class;
            case MessageType.HEAT_BEAT_RESPONSE -> HeartBeatResponse.class;
            case MessageType.SYNC_MESSAGE_REQUEST -> SyncMessageRequest.class;
            case MessageType.APPLY_GROUP_REQUEST -> ApplyGroupRequest.class;
            case MessageType.APPLY_GROUP_RESPONSE -> ApplyGroupResponse.class;
            case MessageType.APPLY_GROUP_SELF_RESPONSE -> ApplyGroupSelfResponse.class;
            case MessageType.ACCEPT_JOIN_GROUP_REQUEST -> AcceptJoinGroupRequest.class;
            case MessageType.ACCEPT_JOIN_GROUP_RESPONSE -> AcceptJoinGroupResponse.class;
            case MessageType.SEND_SMS_REQUEST -> SmsSendRequest.class;
            case MessageType.SEND_SMS_RESPONSE -> SmsSendResponse.class;
            default -> MessageRequest.class;
        };
    }

    private Serializer getSerializer(byte serializeAlgorithm) {
        return Serializer.Default;
    }
}
